﻿using System;
using System.Collections.Generic;
using System.Text;
using ET;
using Marx;
using Server;

namespace Demo
{
    [MessageHandler]
    public class LoginRealmHandler : AMRpcHandler<LoginRequest, LoginResponse>
    {
        protected override async ETTask Run(Session session, LoginRequest request, LoginResponse response, Action reply)
        {
            var realm = session.DomainScene();
            if(realm.Type != MarxSceneType.Realm)
            {
                response.Error = ResultCode.ERR_LoginRealmFail;
                reply();
                return;
            }

            var state = Host.Instance.GetHostState();
            if(state == HostState.Starting)
            {
                response.Error = ResultCode.ERR_ServerNotReady;
                reply();
                return;
            }

            if(state == HostState.Shutting)
            {
                response.Error = ResultCode.ERR_LoginDenied;
                reply();
                return;
            }

            if(string.IsNullOrEmpty(request.Account))
            {
                response.Error = ResultCode.ERR_AccountName;
                response.Message = "账号名格式错误";
                reply();
                return;
            }

            if(!StartConfig.Instance.Zones.Exists(i => i.ID == request.Zone))
            {
                response.Error = ResultCode.ERR_InvalidZone;
                response.Message = "服务器区服错误";
                reply();
                return;
            }

            var db = DBManagerComponent.Instance.GetZoneDB(request.Zone);
            var account = await QueryAccount(db, request.Account, request.Zone);
            if(account == null)
            {
                try
                {
                    account = await RegisterAccount(db, request.Account, request.Password, request.Zone);
                }
                catch (Exception e)
                {
                    Log.Error(e.ToString());
                    response.Error = ResultCode.ERR_RegisterAccount;
                    response.Message = "注册失败";
                    reply();
                    return;
                }
            }
            else
            {
                //if(account.Password != request.Password)
                //{
                //    response.Error = ResultCode.ERR_PasswordError;
                //    response.Message = "密码错误";
                //    reply();
                //    return;
                //}
            }

            var gateSelector = realm.GetComponent<GateSelectorComponent>();
            var gate = await gateSelector.Get(account);
            if(gate == null)
            {
                response.Error = ResultCode.ERR_LoginRealmFail;
                reply();
                return;
            }

            response.GateId = gate.Id;
            response.Address = gate.OuterAddress;
            response.Token = gate.Token;
            response.Players.AddRange(account.Players);

            reply();
            Log.Info("---------------Login Realm Success--------------");
        }

        private async ETTask<Account> QueryAccount(DBComponent db, string name, int zone)
        {
            var accountList = await db.Query<Account>(account => account.Name == name && account.Zone == zone);
            if (accountList.Count > 0)
            {
                return accountList[0];
            }
            return null;
        }

        private async ETTask<Account> RegisterAccount(DBComponent db, string name, string password, int zone)
        {
            Account account = new Account();
            account.Id = IdGenerater.Instance.GenerateUnitId(zone);
            account.Name = name;
            account.Password = password;
            account.Zone = zone;
            account.Players.Add(IdGenerater.Instance.GenerateUnitId(zone));
            await db.Save(account);
            return account;
        }
    }
}
